package com.topnav.mc.involve.solve;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.topnav.mc.admin.entity.Device;
import com.topnav.mc.admin.entity.GbServer;
import com.topnav.mc.admin.entity.bean.DeviceBean;
import com.topnav.mc.admin.entity.param.DeviceParam;
import com.topnav.mc.admin.service.IDeviceService;
import com.topnav.mc.admin.service.IGbServerService;
import com.topnav.mc.involve.http.HttpUtil;
import com.topnav.mc.lock.SyncLock;
import com.topnav.mc.uitls.GbServerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 订阅位置信息
 */
@Component
@Slf4j
public class SubscribePosition {
    @Autowired
    private IGbServerService gbServerService;
    @Autowired
    private IDeviceService deviceService;

    // IP，PORT，deviceId, expires, interval
    private String http="http://%s:%s/api/position/subscribe/%s?expires=%s&interval=%s";

    /**
     * 订阅位置信息
     * @param expires 订阅超时时间 秒 0取消订阅
     * @param interval 上报时间间隔 秒
     */
    @SyncLock(key="SyncGbDeviceSubscribePosition-LOCK",dueSec = 5*60)
    public void subscribe(String expires,String interval){
        String url = null;
        List<String> urlList = new ArrayList<String>();
        QueryWrapper<DeviceParam> wrapper = new QueryWrapper<>();
        //在线的GB 4G执法仪才订阅
        wrapper.eq("d.online",1).eq("d.type",2);
        List<DeviceBean> gbDevices = deviceService.listInfo(wrapper);
        for(DeviceBean dev: gbDevices){
            if (GbServerUtil.get() != null){
                url = String.format(http,GbServerUtil.getIp(),GbServerUtil.getPort(),dev.getCode(),expires,interval);
            }else{
                url = String.format(http,dev.getGbServerHost(),dev.getGbServerApiPort(),dev.getCode(),expires,interval);
            }
            log.debug(url);
            urlList.add(url);

        }
        if (urlList.size() > 0){
            batchProcess(urlList);
        }

    }

    private static CompletableFuture<String> sbscribePosition(String url){
        int i = 0;
        log.debug("sbscribePosition:url={}",url);
        return CompletableFuture.supplyAsync(() -> {
                String result="";
                try {

                    log.info(Thread.currentThread().getName()+":start {}",System.nanoTime());
                    //log.info(Thread.currentThread().getName()+":start {}",System.nanoTime());
                    result  = HttpUtil.doGet(url,null);
                    log.info(Thread.currentThread().getName()+":end {}",System.nanoTime());

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return result;
            });

    }

    public static void batchProcess(List<String> accountIdList) {
        // 并行根据accountId查找对应account
        List<CompletableFuture<String>> accountFindingFutureList =
                accountIdList.stream().map(
                        accountId -> sbscribePosition(accountId)).collect(Collectors.toList()
                );

        // 使用allOf方法来表示所有的并行任务
        CompletableFuture<Void> allFutures =
                CompletableFuture.allOf(accountFindingFutureList.toArray(new CompletableFuture[accountFindingFutureList.size()]));
        //allFutures.join();


        // 下面的方法可以帮助我们获得所有子任务的处理结果
        CompletableFuture<List<String>> finalResults = allFutures.thenApply(v -> accountFindingFutureList.stream().map(accountFindingFuture -> accountFindingFuture.join())
                .collect(Collectors.toList()));

        try {
            List<String> l = finalResults.get();
            System.out.println(l);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
